package com.example.helloword.jcip.chap5.BlockingQueue;

import lombok.extern.slf4j.Slf4j;

import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

@Slf4j
class Producer implements Runnable {
    private final BlockingQueue queue;
    private static Integer seq = 0;
    Producer(BlockingQueue q) { queue = q; }
    public void run() {
        try {
            while (true) {
                Object produce = produce();
                log.info("produce beg put={}", produce);
                queue.put(produce);
//                log.info("produce end put");
            }
        } catch (InterruptedException ex) {
            log.error(String.valueOf(ex.getStackTrace()));
        }
    }
    Object produce() {
        seq++;
        String retSeq = seq.toString();
        return retSeq;
    }
}

@Slf4j
class Consumer implements Runnable {
    private final BlockingQueue queue;
    Consumer(BlockingQueue q) { queue = q; }
    public void run() {
        try {
            while (true) { consume(queue.take()); }
        } catch (InterruptedException ex) {
            log.error(ex.getStackTrace().toString());
        }
    }
    void consume(Object x) {
        log.info("consume thread={} elem={}", Thread.currentThread().getName(), x);
    }
}

class BlockingQueueTester {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue q = new ArrayBlockingQueue(2);
        Producer p = new Producer(q);
        Consumer c1 = new Consumer(q);
        Consumer c2 = new Consumer(q);
        new Thread(p).start();
        new Thread(c1).start();
        new Thread(c2).start();
        Thread.sleep(100000);
    }
}
